﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Reflection;
using System.IO;

namespace Wicresoft.Shell.Core
{
    /// <summary>
    /// store the type infomation and the global variable
    /// </summary>
    public class UmcReflector
    {

        public static Dictionary<string, UmcType> UMCTypes = new Dictionary<string, UmcType>();
        public static Dictionary<string, UmcVariable> GlobalVariables = new Dictionary<string, UmcVariable>();

        private static string GetConfigFile()
        {
            var assemblyLocation = Assembly.GetCallingAssembly().Location;
            var configPath = new FileInfo(assemblyLocation).Directory.FullName;
            return Path.Combine(configPath, "IntelliSenseConfig.xml");

        }
        private static void ReadTypes(XmlDocument xml)
        {
            foreach (XmlNode xn in xml.SelectNodes("//Type"))
            {
                if (xn.Attributes["Name"] != null)
                {
                    UmcType ut = new UmcType(xn.Attributes["Name"].Value);
                    foreach (XmlNode cxn in xn.ChildNodes)
                    {
                        if (cxn.Name == "Property")
                        {
                            if (cxn.Attributes["Name"] != null)
                            {
                                ut.AddProperty(new UmcTypeProperty(cxn.Attributes["Name"].Value,
                                                                    (cxn.Attributes["type"] != null) ? cxn.Attributes["type"].Value : "void",
                                                                    (cxn.Attributes["description"] != null) ? cxn.Attributes["description"].Value : "No description"));

                            }
                        }
                        else if (cxn.Name == "Method")
                        {
                            if (cxn.Attributes["Sign"] != null)
                            {
                                ut.AddMethod(new UmcTypeMethod(cxn.Attributes["Sign"].Value,
                                                               (cxn.Attributes["param"] != null) ? cxn.Attributes["param"].Value : "",
                                                               (cxn.Attributes["type"] != null) ? cxn.Attributes["type"].Value : "void",
                                                               (cxn.Attributes["description"] != null) ? cxn.Attributes["description"].Value : "No description"));
                            }
                        }
                    }
                    UMCTypes.Add(ut.TypeName,ut);
                }
            }
        }
        private static void ReadVariables(XmlDocument xml)
        {
            foreach (XmlNode xn in xml.SelectNodes("//Variables//Variable"))
            {
                if (xn.Attributes["Name"] != null)
                {
                    UmcVariable uv = new UmcVariable(xn.Attributes["Name"].Value,
                                                        xn.Attributes["type"] != null ? xn.Attributes["type"].Value : "void");
                    GlobalVariables.Add(uv.VariableName,uv);
                }
            }
        }
        static UmcReflector()
        {
            XmlDocument xml = new XmlDocument();
            try
            {
                xml.LoadXml(File.ReadAllText(GetConfigFile()));
                ReadTypes(xml);
                ReadVariables(xml);
            }
            catch (Exception ex)
            {
                Logger.Output(ex.Message);
            }
        }


        /*reflect method*/
        public static List<UmcTypeProperty> GetProperties(string aTypeName)
        {
            UmcType ut = UMCTypes[aTypeName];
            if (ut != null)
            {
                return ut.Properties;
            }
            return new List<UmcTypeProperty>();
        }
        public static List<UmcTypeMethod> GetMethods(string aTypeName)
        {
            UmcType ut = UMCTypes[aTypeName];
            if (ut != null)
            {
                return ut.Methods;
            }
            return new List<UmcTypeMethod>();
        }
        public static List<UmcTypeProperty> GetProperties(UmcVariable aVariableName)
        {
            return GetProperties(aVariableName.VariableType);
        }
        public static List<UmcTypeMethod> GetMethods(UmcVariable aVariableName)
        {
            return GetMethods(aVariableName.VariableType);
        }

    }
}
